{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append(\"../\")\n",
    "\n",
    "import os\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "from scorecardpipeline import *\n",
    "\n",
    "\n",
    "logger = init_setting(seed=8888, logger=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>status_of_existing_checking_account</th>\n",
       "      <th>duration_in_month</th>\n",
       "      <th>credit_history</th>\n",
       "      <th>purpose</th>\n",
       "      <th>credit_amount</th>\n",
       "      <th>savings_account_and_bonds</th>\n",
       "      <th>present_employment_since</th>\n",
       "      <th>installment_rate_in_percentage_of_disposable_income</th>\n",
       "      <th>personal_status_and_sex</th>\n",
       "      <th>other_debtors_or_guarantors</th>\n",
       "      <th>...</th>\n",
       "      <th>property</th>\n",
       "      <th>age_in_years</th>\n",
       "      <th>other_installment_plans</th>\n",
       "      <th>housing</th>\n",
       "      <th>number_of_existing_credits_at_this_bank</th>\n",
       "      <th>job</th>\n",
       "      <th>number_of_people_being_liable_to_provide_maintenance_for</th>\n",
       "      <th>telephone</th>\n",
       "      <th>foreign_worker</th>\n",
       "      <th>creditability</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>... &lt; 0 DM</td>\n",
       "      <td>6</td>\n",
       "      <td>critical account/ other credits existing (not at this bank)</td>\n",
       "      <td>radio/television</td>\n",
       "      <td>1169</td>\n",
       "      <td>unknown/ no savings account</td>\n",
       "      <td>... &gt;= 7 years</td>\n",
       "      <td>4</td>\n",
       "      <td>male : divorced/separated</td>\n",
       "      <td>none</td>\n",
       "      <td>...</td>\n",
       "      <td>real estate</td>\n",
       "      <td>67</td>\n",
       "      <td>none</td>\n",
       "      <td>own</td>\n",
       "      <td>2</td>\n",
       "      <td>skilled employee / official</td>\n",
       "      <td>1</td>\n",
       "      <td>yes, registered under the customers name</td>\n",
       "      <td>yes</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1 rows × 21 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "  status_of_existing_checking_account  duration_in_month                                               credit_history           purpose  credit_amount    savings_account_and_bonds present_employment_since  installment_rate_in_percentage_of_disposable_income    personal_status_and_sex other_debtors_or_guarantors  ...     property age_in_years  other_installment_plans housing number_of_existing_credits_at_this_bank                          job number_of_people_being_liable_to_provide_maintenance_for                                 telephone foreign_worker creditability\n",
       "0                          ... < 0 DM                  6  critical account/ other credits existing (not at this bank)  radio/television           1169  unknown/ no savings account           ... >= 7 years                                                    4  male : divorced/separated                        none  ...  real estate           67                     none     own                                       2  skilled employee / official                                                        1  yes, registered under the customers name            yes             0\n",
       "\n",
       "[1 rows x 21 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加载数据集，标签转换为 0 和 1\n",
    "target = \"creditability\"\n",
    "data = germancredit()\n",
    "data[target] = data[target].map({\"good\": 0, \"bad\": 1})\n",
    "\n",
    "# 目前仅支持数值型变量\n",
    "# data = data.select_dtypes(\"number\")\n",
    "data.head(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "rule1 = Rule(\"duration_in_month < 4\")\n",
    "rule2 = Rule(\"credit_amount < 500\")\n",
    "rule3 = Rule(\"purpose.isin(['education', 'business'])\")\n",
    "\n",
    "rules = [rule1, rule2, rule3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# rule1.report(data, target=target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# rule2.report(data, target=target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# rule2.report(data, target=target, prior_rules=rule1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# (rule1 | rule2).report(data, target=target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# (rule1 & rule2).report(data, target=target)\n",
    "# writer = ExcelWriter()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import itertools\n",
    "from functools import reduce\n",
    "\n",
    "\n",
    "max_depth = 3\n",
    "\n",
    "reports = pd.DataFrame()\n",
    "\n",
    "for i in range(max_depth):\n",
    "    for rule in itertools.combinations(rules, i + 1):\n",
    "        if len(rule) > 1:\n",
    "            report = reduce(lambda r1, r2: r1 | r2, list(rule)).report(data, target=target)\n",
    "        else:\n",
    "            report = rule[0].report(data, target=target)\n",
    "        \n",
    "        reports = pd.concat([reports, report])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>规则分类</th>\n",
       "      <th>指标名称</th>\n",
       "      <th>分箱</th>\n",
       "      <th>样本总数</th>\n",
       "      <th>样本占比</th>\n",
       "      <th>好样本数</th>\n",
       "      <th>好样本占比</th>\n",
       "      <th>坏样本数</th>\n",
       "      <th>坏样本占比</th>\n",
       "      <th>坏样本率</th>\n",
       "      <th>LIFT值</th>\n",
       "      <th>坏账改善</th>\n",
       "      <th>准确率</th>\n",
       "      <th>精确率</th>\n",
       "      <th>召回率</th>\n",
       "      <th>F1分数</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>duration_in_month &lt; 4</td>\n",
       "      <td>命中</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.7000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>duration_in_month &lt; 4</td>\n",
       "      <td>未命中</td>\n",
       "      <td>1000.0000</td>\n",
       "      <td>1.0000</td>\n",
       "      <td>700.0000</td>\n",
       "      <td>1.0000</td>\n",
       "      <td>300.0000</td>\n",
       "      <td>1.0000</td>\n",
       "      <td>0.3000</td>\n",
       "      <td>1.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.3000</td>\n",
       "      <td>0.3000</td>\n",
       "      <td>1.0000</td>\n",
       "      <td>0.4615</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>credit_amount &lt; 500</td>\n",
       "      <td>命中</td>\n",
       "      <td>18.0000</td>\n",
       "      <td>0.0180</td>\n",
       "      <td>15.0000</td>\n",
       "      <td>0.0214</td>\n",
       "      <td>3.0000</td>\n",
       "      <td>0.0100</td>\n",
       "      <td>0.1667</td>\n",
       "      <td>0.5556</td>\n",
       "      <td>-0.0081</td>\n",
       "      <td>0.6880</td>\n",
       "      <td>0.1667</td>\n",
       "      <td>0.0100</td>\n",
       "      <td>0.0189</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>credit_amount &lt; 500</td>\n",
       "      <td>未命中</td>\n",
       "      <td>982.0000</td>\n",
       "      <td>0.9820</td>\n",
       "      <td>685.0000</td>\n",
       "      <td>0.9786</td>\n",
       "      <td>297.0000</td>\n",
       "      <td>0.9900</td>\n",
       "      <td>0.3024</td>\n",
       "      <td>1.0081</td>\n",
       "      <td>0.4444</td>\n",
       "      <td>0.3120</td>\n",
       "      <td>0.3024</td>\n",
       "      <td>0.9900</td>\n",
       "      <td>0.4633</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>purpose.isin(['education', 'business'])</td>\n",
       "      <td>命中</td>\n",
       "      <td>147.0000</td>\n",
       "      <td>0.1470</td>\n",
       "      <td>91.0000</td>\n",
       "      <td>0.1300</td>\n",
       "      <td>56.0000</td>\n",
       "      <td>0.1867</td>\n",
       "      <td>0.3810</td>\n",
       "      <td>1.2698</td>\n",
       "      <td>0.0465</td>\n",
       "      <td>0.6650</td>\n",
       "      <td>0.3810</td>\n",
       "      <td>0.1867</td>\n",
       "      <td>0.2506</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>purpose.isin(['education', 'business'])</td>\n",
       "      <td>未命中</td>\n",
       "      <td>853.0000</td>\n",
       "      <td>0.8530</td>\n",
       "      <td>609.0000</td>\n",
       "      <td>0.8700</td>\n",
       "      <td>244.0000</td>\n",
       "      <td>0.8133</td>\n",
       "      <td>0.2860</td>\n",
       "      <td>0.9535</td>\n",
       "      <td>-0.2698</td>\n",
       "      <td>0.3350</td>\n",
       "      <td>0.2860</td>\n",
       "      <td>0.8133</td>\n",
       "      <td>0.4232</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>(duration_in_month &lt; 4) | (credit_amount &lt; 500)</td>\n",
       "      <td>命中</td>\n",
       "      <td>18.0000</td>\n",
       "      <td>0.0180</td>\n",
       "      <td>15.0000</td>\n",
       "      <td>0.0214</td>\n",
       "      <td>3.0000</td>\n",
       "      <td>0.0100</td>\n",
       "      <td>0.1667</td>\n",
       "      <td>0.5556</td>\n",
       "      <td>-0.0081</td>\n",
       "      <td>0.6880</td>\n",
       "      <td>0.1667</td>\n",
       "      <td>0.0100</td>\n",
       "      <td>0.0189</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>(duration_in_month &lt; 4) | (credit_amount &lt; 500)</td>\n",
       "      <td>未命中</td>\n",
       "      <td>982.0000</td>\n",
       "      <td>0.9820</td>\n",
       "      <td>685.0000</td>\n",
       "      <td>0.9786</td>\n",
       "      <td>297.0000</td>\n",
       "      <td>0.9900</td>\n",
       "      <td>0.3024</td>\n",
       "      <td>1.0081</td>\n",
       "      <td>0.4444</td>\n",
       "      <td>0.3120</td>\n",
       "      <td>0.3024</td>\n",
       "      <td>0.9900</td>\n",
       "      <td>0.4633</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>(duration_in_month &lt; 4) | (purpose.isin(['education', 'business']))</td>\n",
       "      <td>命中</td>\n",
       "      <td>147.0000</td>\n",
       "      <td>0.1470</td>\n",
       "      <td>91.0000</td>\n",
       "      <td>0.1300</td>\n",
       "      <td>56.0000</td>\n",
       "      <td>0.1867</td>\n",
       "      <td>0.3810</td>\n",
       "      <td>1.2698</td>\n",
       "      <td>0.0465</td>\n",
       "      <td>0.6650</td>\n",
       "      <td>0.3810</td>\n",
       "      <td>0.1867</td>\n",
       "      <td>0.2506</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>(duration_in_month &lt; 4) | (purpose.isin(['education', 'business']))</td>\n",
       "      <td>未命中</td>\n",
       "      <td>853.0000</td>\n",
       "      <td>0.8530</td>\n",
       "      <td>609.0000</td>\n",
       "      <td>0.8700</td>\n",
       "      <td>244.0000</td>\n",
       "      <td>0.8133</td>\n",
       "      <td>0.2860</td>\n",
       "      <td>0.9535</td>\n",
       "      <td>-0.2698</td>\n",
       "      <td>0.3350</td>\n",
       "      <td>0.2860</td>\n",
       "      <td>0.8133</td>\n",
       "      <td>0.4232</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>(credit_amount &lt; 500) | (purpose.isin(['education', 'business']))</td>\n",
       "      <td>命中</td>\n",
       "      <td>162.0000</td>\n",
       "      <td>0.1620</td>\n",
       "      <td>105.0000</td>\n",
       "      <td>0.1500</td>\n",
       "      <td>57.0000</td>\n",
       "      <td>0.1900</td>\n",
       "      <td>0.3519</td>\n",
       "      <td>1.1728</td>\n",
       "      <td>0.0334</td>\n",
       "      <td>0.6520</td>\n",
       "      <td>0.3519</td>\n",
       "      <td>0.1900</td>\n",
       "      <td>0.2468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>(credit_amount &lt; 500) | (purpose.isin(['education', 'business']))</td>\n",
       "      <td>未命中</td>\n",
       "      <td>838.0000</td>\n",
       "      <td>0.8380</td>\n",
       "      <td>595.0000</td>\n",
       "      <td>0.8500</td>\n",
       "      <td>243.0000</td>\n",
       "      <td>0.8100</td>\n",
       "      <td>0.2900</td>\n",
       "      <td>0.9666</td>\n",
       "      <td>-0.1728</td>\n",
       "      <td>0.3480</td>\n",
       "      <td>0.2900</td>\n",
       "      <td>0.8100</td>\n",
       "      <td>0.4271</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>((duration_in_month &lt; 4) | (credit_amount &lt; 500)) | (purpose.isin(['education', 'business']))</td>\n",
       "      <td>命中</td>\n",
       "      <td>162.0000</td>\n",
       "      <td>0.1620</td>\n",
       "      <td>105.0000</td>\n",
       "      <td>0.1500</td>\n",
       "      <td>57.0000</td>\n",
       "      <td>0.1900</td>\n",
       "      <td>0.3519</td>\n",
       "      <td>1.1728</td>\n",
       "      <td>0.0334</td>\n",
       "      <td>0.6520</td>\n",
       "      <td>0.3519</td>\n",
       "      <td>0.1900</td>\n",
       "      <td>0.2468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>验证规则</td>\n",
       "      <td>((duration_in_month &lt; 4) | (credit_amount &lt; 500)) | (purpose.isin(['education', 'business']))</td>\n",
       "      <td>未命中</td>\n",
       "      <td>838.0000</td>\n",
       "      <td>0.8380</td>\n",
       "      <td>595.0000</td>\n",
       "      <td>0.8500</td>\n",
       "      <td>243.0000</td>\n",
       "      <td>0.8100</td>\n",
       "      <td>0.2900</td>\n",
       "      <td>0.9666</td>\n",
       "      <td>-0.1728</td>\n",
       "      <td>0.3480</td>\n",
       "      <td>0.2900</td>\n",
       "      <td>0.8100</td>\n",
       "      <td>0.4271</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   规则分类                                                                                           指标名称   分箱      样本总数   样本占比     好样本数  好样本占比     坏样本数  坏样本占比   坏样本率  LIFT值    坏账改善    准确率    精确率    召回率   F1分数\n",
       "0  验证规则                                                                          duration_in_month < 4   命中    0.0000 0.0000   0.0000 0.0000   0.0000 0.0000 0.0000 0.0000  0.0000 0.7000 0.0000 0.0000 0.0000\n",
       "1  验证规则                                                                          duration_in_month < 4  未命中 1000.0000 1.0000 700.0000 1.0000 300.0000 1.0000 0.3000 1.0000  0.0000 0.3000 0.3000 1.0000 0.4615\n",
       "0  验证规则                                                                            credit_amount < 500   命中   18.0000 0.0180  15.0000 0.0214   3.0000 0.0100 0.1667 0.5556 -0.0081 0.6880 0.1667 0.0100 0.0189\n",
       "1  验证规则                                                                            credit_amount < 500  未命中  982.0000 0.9820 685.0000 0.9786 297.0000 0.9900 0.3024 1.0081  0.4444 0.3120 0.3024 0.9900 0.4633\n",
       "0  验证规则                                                        purpose.isin(['education', 'business'])   命中  147.0000 0.1470  91.0000 0.1300  56.0000 0.1867 0.3810 1.2698  0.0465 0.6650 0.3810 0.1867 0.2506\n",
       "1  验证规则                                                        purpose.isin(['education', 'business'])  未命中  853.0000 0.8530 609.0000 0.8700 244.0000 0.8133 0.2860 0.9535 -0.2698 0.3350 0.2860 0.8133 0.4232\n",
       "0  验证规则                                                (duration_in_month < 4) | (credit_amount < 500)   命中   18.0000 0.0180  15.0000 0.0214   3.0000 0.0100 0.1667 0.5556 -0.0081 0.6880 0.1667 0.0100 0.0189\n",
       "1  验证规则                                                (duration_in_month < 4) | (credit_amount < 500)  未命中  982.0000 0.9820 685.0000 0.9786 297.0000 0.9900 0.3024 1.0081  0.4444 0.3120 0.3024 0.9900 0.4633\n",
       "0  验证规则                            (duration_in_month < 4) | (purpose.isin(['education', 'business']))   命中  147.0000 0.1470  91.0000 0.1300  56.0000 0.1867 0.3810 1.2698  0.0465 0.6650 0.3810 0.1867 0.2506\n",
       "1  验证规则                            (duration_in_month < 4) | (purpose.isin(['education', 'business']))  未命中  853.0000 0.8530 609.0000 0.8700 244.0000 0.8133 0.2860 0.9535 -0.2698 0.3350 0.2860 0.8133 0.4232\n",
       "0  验证规则                              (credit_amount < 500) | (purpose.isin(['education', 'business']))   命中  162.0000 0.1620 105.0000 0.1500  57.0000 0.1900 0.3519 1.1728  0.0334 0.6520 0.3519 0.1900 0.2468\n",
       "1  验证规则                              (credit_amount < 500) | (purpose.isin(['education', 'business']))  未命中  838.0000 0.8380 595.0000 0.8500 243.0000 0.8100 0.2900 0.9666 -0.1728 0.3480 0.2900 0.8100 0.4271\n",
       "0  验证规则  ((duration_in_month < 4) | (credit_amount < 500)) | (purpose.isin(['education', 'business']))   命中  162.0000 0.1620 105.0000 0.1500  57.0000 0.1900 0.3519 1.1728  0.0334 0.6520 0.3519 0.1900 0.2468\n",
       "1  验证规则  ((duration_in_month < 4) | (credit_amount < 500)) | (purpose.isin(['education', 'business']))  未命中  838.0000 0.8380 595.0000 0.8500 243.0000 0.8100 0.2900 0.9666 -0.1728 0.3480 0.2900 0.8100 0.4271"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "score",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
